/*
 * DispatchingLayerProxy.java   0.0.1    Nov 16, 2009
 * 
 * Copyright (c) 2009 mentalsmash.org
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * The use of the Apache License does not indicate that this project is
 * affiliated with the Apache Software Foundation.
 */
package org.mentalsmash.tazio.net.ril;

//import org.mentalsmash.tazio.net.ril.messages.RILMessage;
import org.mentalsmash.tazio.net.ril.exceptions.FailedMessageDeliveryException;
import org.mentalsmash.tazio.net.ril.exceptions.NoResponseReceivedException;
import org.mentalsmash.tazio.net.ril.impl.AbstractDispatchingLayerProxy;
import org.mentalsmash.tazio.net.ril.messages.MethodInvocationRequestMessage;
import org.mentalsmash.tazio.net.ril.messages.MethodInvocationResponseMessage;
import org.mentalsmash.tazio.net.ril.messages.RILRequestMessage;
import org.mentalsmash.tazio.net.ril.messages.RILResponseMessage;
import org.mentalsmash.tazio.net.ril.rm.RMDispatchingLayerProxy;
import org.mentalsmash.tazio.net.ril.wrm.WRMDispatchingLayerProxy;

/**
 * Classes implementing this interface are responsible for providing methods to
 * allow a {@link BaseRemoteInvoker} and its components to send requests to other
 * RemoteInvokers and receive their responses, using a certain "transport layer"
 * and alerting them if no response was received, by means of a thrown
 * {@link NoResponseReceivedException}.<br/>
 * For the default implementation of this interface see
 * {@link AbstractDispatchingLayerProxy} and the Replica Manager's and Weak
 * Replica Manager's specific implementations of it,
 * {@link RMDispatchingLayerProxy} and {@link WRMDispatchingLayerProxy}.
 * 
 * 
 * @version 0.0.1 Nov 16, 2009
 * @author Andrea Sorbini <as@mentalsmash.org>
 * 
 */
public interface DispatchingLayerProxy {
	/**
	 * Sends a request message to a {@link BaseRemoteInvoker} and returns the
	 * response received from it. Message delivery is guaranteed with an
	 * "at least once" effort.
	 * 
	 * @param msg
	 *            the request message to send
	 * @return a {@link RILResponseMessage} received from the remote host in
	 *         response to the request sent
	 * @throws NoResponseReceivedException
	 *             if no response from the recipient was received .
	 */
	public RILResponseMessage sendMessage(RILRequestMessage msg)
			throws FailedMessageDeliveryException, NoResponseReceivedException;

	/**
	 * Sends a method invocation request to an other {@link BaseRemoteInvoker} with
	 * an "at most once" effort, returning a message containing the invocation's
	 * outcome or throwing a {@link NoResponseReceivedException} if the outcome
	 * is uncertain (i.e. no response was received from the remote host).
	 * 
	 * @param request
	 *            the method invocation to send
	 * @return a {@link MethodInvocationResponseMessage} containing the outcome
	 *         of the remote invocation
	 * @throws NoResponseReceivedException
	 *             if no response was received from the remote host and thus the
	 *             outcome of the invocation is uncertain.
	 */
	public MethodInvocationResponseMessage sendMethodInvocationAtMostOnce(
			MethodInvocationRequestMessage request)
			throws FailedMessageDeliveryException, NoResponseReceivedException;

	/**
	 * Sends a method invocation request to the {@link BaseRemoteInvoker}s currently
	 * subscribe to the group (i.e. the Replica Managers, but don't tell
	 * anybody), returning a message containing the invocation's outcome or
	 * throwing a {@link NoResponseReceivedException} if the outcome is
	 * uncertain (i.e. no response was received from the group).
	 * 
	 * @param msg
	 *            the method invocation to send
	 * @return a {@link MethodInvocationResponseMessage} containing the outcome
	 *         of the remote invocation
	 * @throws NoResponseReceivedException
	 *             if no response was received from the remote host and thus the
	 *             outcome of the invocation is uncertain.
	 */
	public MethodInvocationResponseMessage sendMethodInvocationToGroup(
			MethodInvocationRequestMessage msg)
			throws FailedMessageDeliveryException, NoResponseReceivedException;
}
